1.9.17
版本重构了底层WorkerStop
的机制,实现了异步安全重启的特性。包括stop
、reload
、max_request
3个特性全部复用了一套代码。都支持了异步安全重启。
之前的版本 Worker进程收到SIGTERM
、达到max_request
时,会立即停止服务,这时Worker
进程内可能仍然有事件监听,这些异步任务将会被丢弃。新版本中会先创建新的Worker
,旧的Worker
在完成所有事件之后自行退出。为了防止某些Worker
一直不退出,底层还增加了一个30
秒的定时器,在约定的时间内旧Worker
没有退出,底层会强行终止。
可设置
server->max_wait_time
修改Worker
进程最大等待时间,默认为30
秒
Worker
进程收到SIGTERM
、达到max_request
时,移除管道监听,立即回调onWorkerStop
,并通知Manager
进程。这时当前的Worker
不会再收到任何客户端请求数据Worker
进程会设置一个30
秒的超时定时器,实现退出超时Manager
进程收到Worker
进程的消息后,创建新的Worker
- 新的
Worker
继续处理客户端请求数据 - 旧的
Worker
会持续触发onWorkerExit
事件,PHP
代码可以此事件回调函数中实现清理逻辑 - 旧的
Worker
会持续检测EventLoop
中的socket
数量,在没有任何事件监听后退出进程 - 旧的
Worker
在30
秒内仍然没有完成异步IO
任务,底层强制终止运行,退出进程
为了支持异步重启特性,底层新增了一个onWorkerExit
事件,当旧的Worker
即将退出时,会持续触发onWorkerExit
事件,在此事件回调函数中,应用层可以尝试清理某些长连接Socket
$serv->on('WorkerExit', function (swoole_server $serv, $worker_id) {
$redisState = $serv->redis->getState();
if ($redisState == Swoole\Redis::STATE_READY or $redisState == Swoole\Redis::STATE_SUBSCRIBE)
{
$serv->redis->close();
}
});
$serv->set([
'max_wait_time' => 60,
]);
onWorkerExit 回调功能需要设置 reload_async = true
才能开启
$serv->set(['reload_async' => true]);